package com.gnerv.pabu.basic.core.service.impl;

import com.gnerv.pabu.basic.core.dto.CloudServiceDTO;
import com.gnerv.pabu.basic.core.dto.CloudServiceInstanceDTO;
import com.gnerv.pabu.basic.core.entity.CloudService;
import com.gnerv.pabu.basic.core.service.ICloudService;
import com.netflix.discovery.EurekaClientConfig;
import com.netflix.discovery.endpoint.EndpointUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.client.discovery.health.DiscoveryHealthIndicator;
import org.springframework.cloud.netflix.eureka.CloudEurekaClient;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.ArrayList;
import java.util.List;

@Slf4j
@Service
public class CloudServiceImpl implements ICloudService {

    @Value("${eureka.client.serviceUrl.defaultZone}")
    private String eurekaUrl;

    @Autowired
    private DiscoveryClient discoveryClient;

    @Autowired
    private RestTemplate restTemplate;

    @Override
    public List<CloudServiceDTO> listCloudService() {
        List<CloudServiceDTO> cloudServices = new ArrayList<>(10);
        String url = this.eurekaUrl;
        HttpHeaders requestHeaders = new HttpHeaders();
        requestHeaders.add("contentType", "application/json; charset=utf-8");
        HttpEntity requestEntity = new HttpEntity<>(null, requestHeaders);
        ResponseEntity<CloudService> exchange = restTemplate.exchange(url, HttpMethod.GET, requestEntity, CloudService.class);
        CloudService cloudService;
        if (exchange.getStatusCodeValue() == 200) {
            cloudService = exchange.getBody();
            List<CloudService.ApplicationsBean.ApplicationBean> applications = cloudService.getApplications().getApplication();
            for (CloudService.ApplicationsBean.ApplicationBean application : applications) {
                CloudServiceDTO cloudServiceDTO = new CloudServiceDTO();
                cloudServiceDTO.setName(application.getName());
                int good = 0;
                int bad = 0;
                List<CloudService.ApplicationsBean.ApplicationBean.InstanceBean> instances = application.getInstance();
                for (CloudService.ApplicationsBean.ApplicationBean.InstanceBean instance : instances) {
                    CloudServiceInstanceDTO cloudServiceInstanceDTO = new CloudServiceInstanceDTO();
                    cloudServiceInstanceDTO.setName(instance.getInstanceId());
                    cloudServiceInstanceDTO.setServiceId(instance.getApp());
                    cloudServiceInstanceDTO.setInstanceId(instance.getInstanceId());
                    String name = instance.getStatus();
                    if ("UP".equals(name)) {
                        good++;
                    } else {
                        bad++;
                    }
                    cloudServiceInstanceDTO.setStatus(name);
                    cloudServiceInstanceDTO.setHost(instance.getHostName());
                    cloudServiceInstanceDTO.setUrl(instance.getHomePageUrl());
                    cloudServiceDTO.getChildren().add(cloudServiceInstanceDTO);
                }
                cloudServiceDTO.setGood(good);
                cloudServiceDTO.setBad(bad);
                cloudServices.add(cloudServiceDTO);
            }
        }
        return cloudServices;
    }

    @Override
    public boolean updateCloudServiceStatus(String appId, String instanceId, String status) {
        String url = this.eurekaUrl + appId + "/" + instanceId + "/status?value=" + status;
        ResponseEntity<Object> exchange = restTemplate.exchange(url, HttpMethod.PUT, null, Object.class);
        return true;
    }

}
